package com.example.maze;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import android.os.Parcel;
import android.os.Parcelable;

//deals with player moves
public class Maze implements Parcelable{

	//field to find player's current position
	private Position currentPosition;
	//getting the start position
	private final Position startPosition;
	//finding the finishing line
	private final Position endPosition;
	//field for getting a list for the history
	private final List<Position> history;
	//field for setting the walls for the difficulty
	private final Set<Position> walls;
	
	//setting the details for the maze
	public Maze(Position startPosition, Position endPosition, Set<Position> walls){
		this.startPosition = startPosition;
		this.endPosition = endPosition;
		this.walls = walls;
		this.currentPosition = startPosition;
		this.history = new ArrayList<Position>();
	}
	//checking the move will not run into a wall
	public boolean isMovePossible(Direction direction){
		int x = currentPosition.getX();
		int y = currentPosition.getY();
		switch (direction) {
		case Up:
			//if up button checked it sees what coordinates that would lead us to
			y+=1;
			break;
		case Down:
			y-=1;
			break;
		case Left:
			x-=1;
			break;
		case Right:
			x+=1;
			break;
		}
		//if the list of walls does not contain the new coordinates returns true
		return !walls.contains(new Position(x, y));
	}
	//making the move
	public Position move(Direction direction){
		//gets the current position
		int x = currentPosition.getX();
		int y = currentPosition.getY();
		switch (direction) {
		case Up:
			//adds 1 to the relevant axis
			y+=1;
			break;
		case Down:
			y-=1;
			break;
		case Left:
			x-=1;
			break;
		case Right:
			x+=1;
			break;
		}
		//updates the history by adding the old current position to the history
		history.add(currentPosition);
		//sets the current position to the new position and returns it
		currentPosition = new Position(x,y);
		return currentPosition;
	}
	//finding if the user has reached the finishing point
	public boolean isItTheEnd(){
		return endPosition.equals(currentPosition);
	}
	//getting the total moves to be displayed to the user
	public int getTotalMoves(){
		return history.size();
	}
	//returning end position
	public Position getEndPosition(){
		return endPosition;
	}
	//returning the current position
	public Position getCurrentPosition(){
		return currentPosition;
	}
	
	@Override
	public int describeContents() {
		return 0;
	}
	
	//sending the data to the parcelable
	@Override
	public void writeToParcel(Parcel dest, int flags) {
		dest.writeParcelable(currentPosition, flags);
		dest.writeParcelable(startPosition, flags);
		dest.writeParcelable(endPosition, flags);
		dest.writeList(history);
		dest.writeList(new ArrayList<Position>(walls));
	}
	
	
	public static final Parcelable.Creator<Maze> CREATOR = new Parcelable.Creator<Maze>() {
		
		public Maze createFromParcel(Parcel in) {
			return new Maze(in);
		}

		@Override
		public Maze[] newArray(int size) {
			return new Maze[size];
		}
	};

	private Maze(Parcel in) {
		this.currentPosition = in.readParcelable(Position.class.getClassLoader());
		this.startPosition = in.readParcelable(Position.class.getClassLoader());
		this.endPosition = in.readParcelable(Position.class.getClassLoader());
		this.history = new ArrayList<Position>();
		in.readList(history, Position.class.getClassLoader());
		List<Position> tempWalls = new ArrayList<Position>();
		in.readList(tempWalls, Position.class.getClassLoader());
		this.walls = new HashSet<Position>(tempWalls);
	}
}
